using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using NovodexWrapper;

/// <summary>
/// parent class containing a set of animation methods
/// </summary>
/// 
namespace marbletrack
{
    public abstract class Obstacle
    {
        public Vector3 modelRotation_;
        public float modelScale_;
        public Vector3 modelPosition_ = new Vector3(Game1.GRIDBOUNDRY, -2 * Game1.GRIDBOUNDRY, Game1.GRIDBOUNDRY);
        protected ModelClass model_;
        public Vector3 nextModelPosition_;
        public Texture2D texture = Game1.metal1;//loads texture into all inherited classes
        protected Matrix transformMatrix_;
        protected Physics physics;
        protected NxActor trackActor_;
        public Matrix CorrectPosition_ = Matrix.Identity;
        public bool active = false;
        public float mouseClickTolerance = Game1.SQUARESIZE;
        protected float height = 0;
        protected float bounceAngle = 0;

        public NxActor Actor
        {
            get { return trackActor_; }
        }

        public Obstacle()
        {
            modelPosition_ = Vector3.Zero;
            physics = Game1.GetPhysics;
        }

        internal abstract void SetupVariables(Vector3 rotation, Vector3 modelPosition);

        public void CorrectAngle(ref float angle)
        {
            //corrects model rotation so value doesnt get unneccesarily high
            if (angle > 360)
            {
                angle = 0;
            }
            else if (angle < 0)
            {
                angle = 360;
            }
        }

        public void MakeItBounce(float multiplier)
        {
            //moves objects up and down y axis
            modelPosition_.Y = nextModelPosition_.Y = height + (Game1.SQUARESIZE * multiplier * (float)(Math.Sin(MathHelper.ToRadians(bounceAngle++))));
            if (bounceAngle > 360)
            {
                bounceAngle = 0;
            }
        }

        public void CreateMovement(float speed)
        {
            //moves object at desired speed
            if (Vector3.Distance(modelPosition_, nextModelPosition_) > Game1.HALFSQUARESIZE)
            {
                modelPosition_ += (nextModelPosition_ - modelPosition_) / speed;
            }
            else
            {
                modelPosition_ = nextModelPosition_;
            }
        }

        public void CreateRotationY(float speed)
        {
            //spins model round y - axis
            modelRotation_.Y += speed;
        }

        public abstract void Update();

        //Create a transformation matrix that converts from Object Space -> World Space
        protected Matrix ApplyTransformations()
        {
            Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(
                MathHelper.ToRadians(modelRotation_.Y),
                MathHelper.ToRadians(modelRotation_.X),
                MathHelper.ToRadians(modelRotation_.Z));
            Matrix scaleMatrix = Matrix.CreateScale(modelScale_);
            Matrix translationMatrix = Matrix.CreateTranslation(modelPosition_);
            return CorrectPosition_ * rotationMatrix * scaleMatrix * translationMatrix;
        }

        public abstract void Draw();
    }
}